package Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MenuListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Decorations;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import Command.LDrawColor;
import Command.LDrawColorT;
import LDraw.Files.LDrawFile;
import LDraw.Files.LDrawMPDModel;
import LDraw.Support.ColorLibrary;
import Notification.ILDrawSubscriber;
import Notification.INotificationMessage;
import Notification.NotificationCenter;
import Notification.NotificationMessageT;
import Resource.ResourceManager;
public class ModelListView implements ILDrawSubscriber, Listener,
DragSourceListener {
private Display display;
private Shell shell;
private Composite parent;
private TreeEditor editor;
private Tree treeComponent = null;
private Image folderImage;
public ModelListView(Composite parent, int style) {
this.parent = parent;
display = parent.getDisplay();
shell = parent.getShell();
NotificationCenter.getInstance().addSubscriber(this,
NotificationMessageT.LDrawFileActiveModelDidChanged);
generateView(parent);
drawTree();
}
private void drawTree() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
MOCBuilder builder = MOCBuilder.getInstance();
LDrawFile file = builder.getWorkingLDrawFile();
if (file == null)
return;
if (!treeComponent.isDisposed()) {
treeComponent.setVisible(false);
treeComponent.removeAll();
LDrawMPDModel mainModel = null;
try {
mainModel = file.submodels().get(0);
} catch (Exception e) {
e.printStackTrace();
}
if (mainModel == null)
return;
TreeItem mainModelTreeItem = new TreeItem(treeComponent,
SWT.NONE);
mainModelTreeItem.setText(mainModel.modelName());
mainModelTreeItem.setData(mainModel);
mainModelTreeItem.setImage(folderImage);
if (MOCBuilder.getInstance().getActiveModel() == mainModel)
setBold(mainModelTreeItem);
for (LDrawMPDModel model : file.submodels()) {
if (model == mainModel)
continue;
TreeItem treeItem = new TreeItem(mainModelTreeItem,
SWT.NONE);
treeItem.setText(model.modelName().trim());
treeItem.setData(model);
if (MOCBuilder.getInstance().getActiveModel() == model)
setBold(treeItem);
}
mainModelTreeItem.setExpanded(true);
treeComponent.setVisible(true);
}
}
});
}
private void generateView(Composite parent) {
GridLayout layout = new GridLayout();
layout.marginTop = -5;
layout.marginLeft = -5;
layout.marginRight = -5;
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(layout);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Label label = new Label(composite, SWT.NONE);
label.setText("Submodels");
treeComponent = new Tree(composite, SWT.MULTI | SWT.BORDER);
treeComponent.setLayout(new GridLayout());
treeComponent
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
treeComponent.setMenu(createPopupMenu(parent.getShell()));
folderImage = ResourceManager.getInstance().getImage(display,
"/Resource/Image/folder_brick.png");
treeComponent.addMouseListener(new MouseListener() {
@Override
public void mouseUp(MouseEvent e) {
}
@Override
public void mouseDown(MouseEvent e) {
}
@Override
public void mouseDoubleClick(MouseEvent e) {
TreeItem[] selectedItems = treeComponent.getSelection();
if (selectedItems.length == 1) {
Object object = selectedItems[0].getData();
if (object instanceof LDrawMPDModel == false)
return;
MOCBuilder.getInstance().changeActiveModel(
(LDrawMPDModel) object);
setBold(selectedItems[0]);
}
}
});
treeComponent.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent arg0) {
switch (arg0.keyCode) {
case SWT.DEL:
handleDelete();
break;
case SWT.F2:
handleRename();
break;
}
}
@Override
public void keyReleased(KeyEvent arg0) {
}
});
DragSource source = new DragSource(treeComponent, DND.DROP_COPY | DND.DROP_MOVE);
source.setTransfer(new Transfer[] { TextTransfer.getInstance() });
source.addDragListener(this);
editor = new TreeEditor(treeComponent);
editor.horizontalAlignment = SWT.LEFT;
editor.grabHorizontal = true;
editor.minimumWidth = 50;
}
@Override
public void receiveNotification(NotificationMessageT messageType,
INotificationMessage msg) {
display.asyncExec(new Runnable() {
@Override
public void run() {
drawTree();
}
});
}
private Menu createPopupMenu(Decorations parent) {
Menu menu = new Menu(parent, SWT.POP_UP);
final MenuItem renameItem = new MenuItem(menu, SWT.PUSH);
renameItem.setText("Rename");
renameItem.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
handleRename();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
final MenuItem deleteItem = new MenuItem(menu, SWT.PUSH);
deleteItem.setText("Delete");
deleteItem.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
handleDelete();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
menu.addMenuListener(new MenuListener() {
@Override
public void menuShown(MenuEvent e) {
int count = treeComponent.getSelectionCount();
if (count > 1) {
renameItem.setEnabled(false);
deleteItem.setEnabled(true);
} else if (count == 1) {
renameItem.setEnabled(true);
deleteItem.setEnabled(true);
} else {
renameItem.setEnabled(false);
deleteItem.setEnabled(false);
}
}
@Override
public void menuHidden(MenuEvent e) {
}
});
return menu;
}
private void renameModel(TreeItem item, LDrawMPDModel model) {
final Text newEditor = new Text(treeComponent, SWT.NONE);
newEditor.setText(model.modelName());
newEditor.addListener(SWT.FocusOut, this);
newEditor.addListener(SWT.KeyUp, this);
newEditor.selectAll();
newEditor.setFocus();
editor.setEditor(newEditor, item);
}
@Override
public void handleEvent(Event event) {
Text text = (Text) editor.getEditor();
if (event.keyCode == 0 || event.keyCode == SWT.CR) {
String name = text.getText();
TreeItem item = editor.getItem();
LDrawMPDModel model = (LDrawMPDModel) item.getData();
MOCBuilder.getInstance().renameModel(model, name);
item.setText(name);
text.dispose();
} else if (event.keyCode == SWT.ESC) {
text.dispose();
}
}
private void setBold(TreeItem selectedItem) {
Display display = treeComponent.getDisplay();
if (treeComponent.getFont() == null)
return;
FontData datas[] = treeComponent.getFont().getFontData();
for (FontData data : datas) {
data.setStyle(SWT.NORMAL);
}
Font normalFont = new Font(display, datas);
for (FontData data : datas) {
data.setStyle(SWT.BOLD);
}
Font boldFont = new Font(display, datas);
for (TreeItem item : treeComponent.getItems()) {
if (item.equals(selectedItem)) {
item.setFont(boldFont);
} else {
item.setFont(normalFont);
}
if (item.getItems().length != 0)
for (TreeItem item2 : item.getItems()) {
if (item2.equals(selectedItem)) {
item2.setFont(boldFont);
} else {
item2.setFont(normalFont);
}
}
}
}
@Override
public void dragStart(DragSourceEvent event) {
if (treeComponent.getSelection().length != 1)
return;
LDrawColor color = ColorLibrary.sharedColorLibrary().colorForCode(
LDrawColorT.LDrawCurrentColor);
DNDTransfer.getInstance().setColor(color);
event.image = null;
Object object = null;
Control control = ((DragSource) event.getSource()).getControl();
if (control.equals(treeComponent)) {
object = treeComponent.getSelection()[0].getData();
}
if (object == null) {
return;
} else {
DNDTransfer.getInstance().setData(((LDrawMPDModel)object).modelName());
}
}
@Override
public void dragSetData(DragSourceEvent event) {
if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
event.data = DNDTransfer.getInstance().getData();
}
}
@Override
public void dragFinished(DragSourceEvent event) {
DNDTransfer.getInstance().end();
}
public void handleDelete(){
TreeItem[] selectedItems = treeComponent.getSelection();
if (selectedItems.length == 1) {
Object object = selectedItems[0].getData();
if (object instanceof LDrawMPDModel) {
LDrawMPDModel model = (LDrawMPDModel) object;
MOCBuilder.getInstance().removeModel(model);
}
}
GlobalFocusManager.getInstance().forceFocusToMainView();
}
public void handleRename(){
TreeItem[] selectedItems = treeComponent.getSelection();
if (selectedItems.length == 1) {
Object object = selectedItems[0].getData();
if (object instanceof LDrawMPDModel) {
LDrawMPDModel model = (LDrawMPDModel) object;
renameModel(selectedItems[0], model);
}
}
}
}